package com.zj.esproxy.interfaces.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import com.zj.baseproxy.enums.TypeEnum;
import com.zj.baseproxy.interfaces.HttpHandler;
import com.zj.esproxy.enums.AggTypeEnum;
import com.zj.esproxy.interfaces.EsProxy;
import com.zj.esproxy.model.Agg;
import com.zj.esproxy.model.EsInfo;
import com.zj.esproxy.model.EsPage;
import com.zj.esproxy.utils.EsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author arthur_zhou
 * @date 2024/4/11 14:11
 */
@Slf4j
public class EsProxyImpl implements EsProxy {

    @Resource
    private HttpHandler httpHandler;

    @Override
    public JSONObject getJsonData(EsInfo esInfo, String json) {
        JSONObject jsonObject = requestEs(esInfo, json);
        return Objects.isNull(jsonObject) ? new JSONObject() : jsonObject;
    }

    @Override
    public <T> EsPage<T> getData(Class<T> clazz, EsInfo esInfo, String json) {
        JSONObject jsonObject = requestEs(esInfo, json);
        if (CollectionUtil.isEmpty(jsonObject)) {
            return EsPage.setPageData();
        }
        long total = jsonObject.getLongValue("total_count");
        JSONArray result = jsonObject.getJSONArray("result");
        List<T> items = Collections.emptyList();
        if (CollectionUtil.isNotEmpty(result)) {
            items = result.toJavaList(clazz);
        }
        String aggregations = jsonObject.getString("aggregations");
        return EsPage.setPageData(items, total, EsUtil.getAggList(aggregations));
    }

    @Override
    public <T> EsPage<T> getDistinctData(Class<T> clazz, EsInfo esInfo, String json) {
        EsPage<T> dataPage = getData(clazz, esInfo, json);
        if (CollectionUtil.isEmpty(dataPage.getBuckets())) {
            log.info("es：没有找聚合去重信息");
            return dataPage;
        }
        List<Agg> buckets = dataPage.getBuckets();
        long distinctTotal = buckets.stream().filter(v -> AggTypeEnum.cardinality.equals(v.getType()))
                .map(Agg::getValue)
                .findFirst()
                .map(BigDecimal::longValue)
                .orElse(0L);
        dataPage.setTotal(distinctTotal);
        return dataPage;
    }

    /**
     * 请求es
     *
     * @param esInfo es路径
     * @param json   请求json
     * @return 响应json
     */
    private JSONObject requestEs(EsInfo esInfo, String json) {
        if (Objects.isNull(esInfo)) {
            log.error("es请求失败：没有找到es信息");
            return null;
        }
        if (StringUtils.isEmpty(esInfo.getUrl())) {
            log.error("es请求失败：没有找到es路径");
            return null;
        }
        if (StringUtils.isEmpty(esInfo.getProject())) {
            log.error("es请求失败：没有找到es索引");
            return null;
        }
        // 解析请求报文 拼接esInfo后缀
        JSONObject requestJson = JSONObject.parseObject(json);
        StringBuilder stringBuilder = new StringBuilder(esInfo.getUrl());
        stringBuilder.append("?project=").append(esInfo.getProject());
        String product = requestJson.getString("product");
        if (StringUtils.isNotBlank(product)) {
            stringBuilder.append("&product=").append(product);
        }
        String operation = requestJson.getString("operation");
        if (StringUtils.isNotBlank(operation)) {
            stringBuilder.append("&operation=").append(operation);
        }
        String queryId = requestJson.getString("query_id");
        if (StringUtils.isEmpty(queryId)) {
            // queryId随机
            queryId = UUID.randomUUID().toString();
        }
        stringBuilder.append("&query_id=").append(queryId);
        // 获取数据
        String responseJson = httpHandler.post(TypeEnum.ES, stringBuilder.toString(), json);
        if (StringUtils.isEmpty(responseJson)
                || !JSONValidator.Type.Object.equals(JSONValidator.from(responseJson).getType())) {
            log.error("es响应解析错误：{}", responseJson);
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(responseJson);
        if (CollectionUtil.isEmpty(jsonObject)) {
            return null;
        }
        String error = jsonObject.getString("err");
        if (StringUtils.isNotEmpty(error)) {
            log.error("es报错：{}", error);
            return null;
        }
        long total = jsonObject.getLongValue("total_count");
        // 如果查询了总数且为0
        if (total == 0L) {
            return null;
        }
        return jsonObject;
    }

}
